
/* Label	GPIO	Input	Output	Notes
D0	GPIO16	无中断	无 Pwm 或 I2c 支持	HIGH at boot used to wake up from deep sleep
D1	GPIO5	OK	OK	常用作SCL（I2C）
D2	GPIO4	OK	OK	常用作SDA（I2C）
D3	GPIO0	上拉	OK	connected to FLASH button, boot fails if pulled LOW
D4	GPIO2	上拉	OK	HIGH at boot connected to on-board LED, boot fails if pulled LOW
D5	GPIO14	OK	OK	SPI (SCLK)
D6	GPIO12	OK	OK	SPI (MISO)
D7	GPIO13	OK	OK	SPI (MOSI)
D8	GPIO15	下拉	OK	SPI (CS) Boot fails if pulled HIGH
RX	GPIO3	OK	RX	HIGH at boot
TX	GPIO1	TX	OK	HIGH at boot debug output at boot, boot fails if pulled LOW
A0	ADC0	模拟引脚	X	 */
#include "Controller.h"
// 定义 controller 对象
Controller controller;
void (*Controller::eventCallback)(const String &);
void Controller::setEventCallback(void (*callback)(const String &)) {
  eventCallback = callback;  // 设置回调函数
  Serial.println("setEventCallback被调用");
  /* 设置中断处理 */
  attachInterrupt(PIN_OPEN_STATUS, openFun,FALLING);                                             //设置上限位下降沿触发中断
  attachInterrupt(PIN_CLOSE_STATUS, closeFun,FALLING);                                           //设置下限位下降沿触发中断
  /* 两个引脚会有一个为低电平视为电机工作 为何要采用低电平因为电机工作电压为12v,只能串接二极管*/  //---------------------------------默认电机不工作为断开模式----------------------------------
  attachInterrupt(PIN_MOTOR_STATUS_OPEN, motorOpenFun, CHANGE);                                   //设置电机开车库改变降沿触发中断
  attachInterrupt(PIN_MOTOR_STATUS_CLOSE, motorCloseFun, CHANGE);
}
Controller::Controller() {
  /* 用于控制继电器 */
  pinMode(PIN_OPEN, OUTPUT);   //初始化引脚D1
  pinMode(PIN_CLOSE, OUTPUT);  //初始化引脚D2
  /* 用于判断车库开关状态,检测车库上下限位 */
  pinMode(PIN_OPEN_STATUS, INPUT_PULLUP);   //初始化引脚D6为输入上拉
  pinMode(PIN_CLOSE_STATUS, INPUT_PULLUP);  //初始化引脚D7为输入上拉
  /* 用于判断电机正反转从而判断开关状态 */
  pinMode(PIN_MOTOR_STATUS_OPEN, INPUT_PULLUP);   //初始化引脚D5为输入上拉,低电平开门------------------------------这个需要测试电机---------------------------------------
  pinMode(PIN_MOTOR_STATUS_CLOSE, INPUT_PULLUP);  //初始化引脚D8为输入上拉,低电平关门------------------------------这个需要测试电机---------------------------------------


  /* 初始化继电器引脚为高电平 */
  digitalWrite(PIN_OPEN, HIGH);
  digitalWrite(PIN_CLOSE, HIGH);
  //设置电机关车库改变降沿触发中断
  /* 两个引脚都为高电平视为电机停止工作 */
  /*  attachInterrupt(PIN_MOTOR_STATUS_OPEN, pauseFun, RISING);       //设置电机暂停开车库上升沿触发中断
  attachInterrupt(PIN_MOTOR_STATUS_CLOSE, pauseFun, RISING);  */
  //设置电机暂停关车库上升沿触发中断 */
  //digitalPinToInterrupt(pin)//设置电路板引脚
  //detachInterrupt(pin);    取消指定引脚的中断
  // 临时禁用中断，执行关键操作
  //cli();  // 禁用中断
  //sei();  // 启用中断
  //delayMicroseconds(10000);//微秒延迟
  // millis();//获取毫秒时间
  //micros();获取微秒时间
  //ICACHE_RAM_ATTR主要用与中断函数的快速处理
  //IRAM_ATTR主要用于普通函数的快速处理
  //FALLING下降沿触发,CHANGE改变沿触发,RISING 上升沿触发,ONHIGH 高电平触发,ONLOW 低电平触发
}
String Controller::readSwitch() {
  String onOff = "halfway";
  if (!digitalRead(PIN_OPEN_STATUS)) {
    onOff = "opened";
  } else if (!digitalRead(PIN_CLOSE_STATUS)) {
    onOff = "closed";
  }
  return "{\"status\":\"" + onOff + "\"}";
}
String Controller::readMotor() {
  String onOff = "stopping";
  if (!digitalRead(PIN_MOTOR_STATUS_OPEN)) {
    onOff = "opening";
  } else if (!digitalRead(PIN_MOTOR_STATUS_CLOSE)) {
    onOff = "closing";
  }
  return "{\"status\":\"" + onOff + "\"}";
}
void Controller::open() {
  digitalWrite(PIN_OPEN, LOW);  //设置D1为低电平时关闭
  ticker.once(1, []() {
    digitalWrite(PIN_OPEN, HIGH);  //保持低电平1秒后抬高
  });
}
void Controller::close() {
  digitalWrite(PIN_CLOSE, LOW);  //设置D2为低电平时关闭
  ticker2.once(1, []() {
    digitalWrite(PIN_CLOSE, HIGH);  //保持低电平1秒后抬高
  });
}
/* 中断的执行函数 */
void ICACHE_RAM_ATTR Controller::openFun() {  //"车库已打开"
  
  delayMicroseconds(100000);  //微秒延迟
  bool status = digitalRead(PIN_CLOSE_STATUS);
  if (digitalRead(PIN_OPEN_STATUS) != status) eventCallback("{\"status\":\"opened\"}");
}
void ICACHE_RAM_ATTR Controller::closeFun() {  //"车库已关闭"

  delayMicroseconds(100000);  //微秒延迟LOW
    bool status = digitalRead(PIN_OPEN_STATUS);
  if (!digitalRead(PIN_CLOSE_STATUS) != status) eventCallback("{\"status\":\"closed\"}");
}
void ICACHE_RAM_ATTR Controller::motorOpenFun() {  //电机开车库中
  delayMicroseconds(100000);                       //微秒延迟
  if (digitalRead(PIN_MOTOR_STATUS_OPEN) == LOW && digitalRead(PIN_MOTOR_STATUS_CLOSE) == HIGH) {
    eventCallback("{\"status\":\"opening\"}");
  } else {
    eventCallback("{\"status\":\"stopping\"}");
  }
}
void ICACHE_RAM_ATTR Controller::motorCloseFun() {  //电机关车库中
  delayMicroseconds(100000);                        //微秒延迟
  if (digitalRead(PIN_MOTOR_STATUS_CLOSE) == LOW && digitalRead(PIN_MOTOR_STATUS_OPEN) == HIGH) {
    eventCallback("{\"status\":\"closing\"}");
  } else {
    eventCallback("{\"status\":\"stopping\"}");
  }
}

/* void ICACHE_RAM_ATTR Controller::pauseFun() {
  bool status=digitalRead(PIN_MOTOR_STATUS_OPEN);
  delayMicroseconds(100000);//微秒延迟
  if(digitalRead(PIN_MOTOR_STATUS_OPEN)==digitalRead(PIN_MOTOR_STATUS_CLOSE) && status==true)Serial.println("电机中断");
}; */